﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WsProtocol.IEC62056.DataTypeClass;
using Comm.PublicClass;

namespace WsProtocol.IEC62056.CosemACSE
{ 
    /// <summary>
    /// transaction-id OCTET STRING, 
    //originator-system-title OCTET STRING, 
    //recipient-system-title OCTET STRING, 
    //date-time OCTET STRING, 
    //other-information OCTET STRING, 
    //key-info Key-Info OPTIONAL, 
    //ciphered-content OCTET STRING
    /// </summary>
    public class GeneralCiphering
    {
        public static string Request(CosemObject OI, ref string errorinfo)
        {
            try
            {
                string formatvalue = string.Empty;
                ElementData eleNode = OI.DataNode;
                string choice = eleNode.SetValue;
                
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[0], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[1], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[2], ref errorinfo);
                //if(eleNode.eleNodeList[3].DataTypeDIY!="")
                //    string sDate=Data.GetPreFormatValue()
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[3], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[4], ref errorinfo);
                if (choice == "1")
                    formatvalue += "01" + KeyInfo.GetFormatValue(eleNode.eleNodeList[5], ref errorinfo);
                else
                    formatvalue += "00";
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[6], ref errorinfo);
                return formatvalue;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }


        public static int Response(ref string frameData, CosemObject OI, ref string errorinfo)
        {
            try
            {
                int iresult = 0;
                if (OI.ParEleNode == null)
                    OI.ParEleNode = new ElementData();
                ElementData eleNode = OI.ParEleNode;
                for (int i = 0; i < 5; i++) {
                    if (i >= eleNode.eleNodeList.Count)
                        eleNode.eleNodeList.Add(new ElementData());
                    iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[i], ref errorinfo);
                }

                while (eleNode.eleNodeList.Count < 7)
                    eleNode.eleNodeList.Add(new ElementData());

                string choice = frameData.Substring(0, 2);
                frameData = frameData.Substring(2);
                if (choice == "01")
                {                    
                    iresult = KeyInfo.AnalizeData(ref frameData, eleNode.eleNodeList[5], ref errorinfo);
                }
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[6], ref errorinfo);

               // eleNode.ReadValue = choice;

                return iresult;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return -1;
            }
        }
    }

    public class GeneralGloCiphering
    {
        public static string Request(string sysTitle,string CipherData, ref string errorinfo)
        {
            try
            {
                string formatvalue = string.Empty;
                formatvalue = octString.GetFormatValue(sysTitle, ref errorinfo);
                formatvalue += octString.GetFormatValue(CipherData, ref errorinfo);

                return formatvalue;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }

        public static int Response(ref string frameData, CosemObject OI, ref string errorinfo)
        {
            int iResult = 0;
            try
            {
                if (string.IsNullOrEmpty(frameData))
                {
                    errorinfo = "解析数据为空";
                    return -1;
                }
                frameData = frameData.Substring(2); //去掉glo
                if (OI.ParEleNode == null)
                    OI.ParEleNode = new ElementData();
                OI.ParEleNode.ReadValue = octString.AnalizeDataSpecial(ref frameData, ref errorinfo);//解析出system-stitile 暂时放附加参数节点里
                frameData = "DB" + frameData;  //为了统一代码
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                iResult = -1;
            }
            return iResult;

        }
        
    }

    public class GeneralDedCiphering : GeneralGloCiphering
    {
    }

    public class GeneralSigning
    {
        public static string Request(CosemObject OI, ref string errorinfo)
        {
            try
            {
                string formatvalue = string.Empty;
                ElementData eleNode = OI.DataNode;
                string choice = eleNode.SetValue;
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[0], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[1], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[2], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[3], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[4], ref errorinfo);
                formatvalue += "01" + KeyInfo.GetFormatValue(eleNode.eleNodeList[5], ref errorinfo);
                formatvalue += octString.GetFormatValue(eleNode.eleNodeList[6], ref errorinfo);
                return formatvalue;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return string.Empty;
            }
        }


        public static int Response(ref string frameData, CosemObject OI, ref string errorinfo)
        {
            try
            {
                int iresult = 0;
                if (OI.ParEleNode == null)
                    OI.ParEleNode = new ElementData();
                ElementData eleNode = OI.ParEleNode;
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[0], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[1], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[2], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[3], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[4], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[5], ref errorinfo);
                iresult = octString.AnalizeData(ref frameData, eleNode.eleNodeList[6], ref errorinfo);

                return iresult;
            }
            catch (Exception ex)
            {
                errorinfo = ex.ToString();
                return -1;
            }

        }
    }

    public class GeneralBlockTransfer {
        
        public static int Response(ref string frameData,ref long frameseq, ref bool finished, ref string RawData) {
            //Block-Control ::= Unsigned8  hxh
            //window bits 0-5       window advertise
            //-- streaming bit 6    0 = No Streaming active, 1 = Streaming active
            //-- last-block bit 7   0 = Not Last Block, 1 = Last Block   
            try
            {
                int iresult = 0;
                string bControl = MyConvert.HexToBin(frameData.Substring(0, 2));

                finished = bControl.Substring(0, 1) == "1";

                frameseq = Convert.ToInt64(frameData.Substring(2, 4), 16);//帧序号unsigned16 
                frameData = frameData.Remove(0,6);

                int bACK = Convert.ToInt32(frameData.Substring(0, 4), 16);
                frameData = frameData.Remove(0,4);
                string errorinfo = string.Empty;
                RawData = octString.AnalizeDataSpecial(ref frameData, ref errorinfo);
                return iresult;
            }
            catch (Exception ex)
            {               
                return -1;
            }
        }
    }
}
